package com.liaoyifan.core.valid;

import com.liaoyifan.core.exception.ResultException;
import io.swagger.v3.oas.annotations.media.Schema;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Map;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ReflectionUtils;

@SuppressWarnings("unused")
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Assert {

    public static void isTrue(boolean expression, String message) {
        if (!expression) {
            throw new ResultException(message);
        }
    }

    public static void notNull(Object object, String message) {
        if (object == null) {
            throw new ResultException(message);
        }
    }

    public static void notBlank(CharSequence str, String message) {
        if (Lang.isBlank(str)) {
            throw new ResultException(message);
        }
    }

    public static void notEmpty(Map<?, ?> map, String message) {
        if (map == null || map.isEmpty()) {
            throw new ResultException(message);
        }
    }

    public static void notEmpty(Object[] array, String message) {
        if (array == null || array.length == 0) {
            throw new ResultException(message);
        }
    }

    public static void notEmpty(Collection<?> collection, String message) {
        if (collection == null || collection.isEmpty()) {
            throw new ResultException(message);
        }
    }

    @SneakyThrows
    public static void require(Object object, String... fieldNames) {
        notNull(object, "object cannot be null");
        for (String fieldName : fieldNames) {
            notBlank(fieldName, "fieldName cannot be blank");
            Field field = ReflectionUtils.findField(object.getClass(), fieldName);
            if (field == null) {
                throw new IllegalArgumentException(
                        object.getClass().getName() + " not found field: " + fieldName);
            }
            ReflectionUtils.makeAccessible(field);
            Object value = field.get(object);
            if (Lang.isEmpty(value)) {
                Schema annotation = AnnotationUtils.getAnnotation(field, Schema.class);
                throw new ResultException(
                        annotation != null
                                ? annotation.description()
                                : field.getName() + " cannot be blank");
            }
        }
    }
}
